<template>
  <div v-loading="loading" class="container">

    <el-form ref="form" :inline="true" label-position="left" size="mini">

      <el-form-item label="Instance:">
        <el-select
          v-model="instanceSelectCondition"
          style="min-width: 260px"
          clearable
          filterable
          placeholder="请选择"
        >
          <el-option
            v-for="item in instanceSelecteds"
            :key="item.instance"
            :label="item.instance"
            :value="item.instance"
          />
        </el-select>
      </el-form-item>

      <!--      <el-form-item label="Database:">-->
      <!--        <el-select-->
      <!--          v-model="databaseSelectCondition"-->
      <!--          style="min-width: 260px"-->
      <!--          clearable-->
      <!--          filterable-->
      <!--          placeholder="请选择"-->
      <!--        >-->
      <!--          <el-option-->
      <!--            v-for="item in databaseSelecteds"-->
      <!--            :key="item.instance"-->
      <!--            :label="item.instance"-->
      <!--            :value="item.instance"-->
      <!--          />-->
      <!--        </el-select>-->
      <!--      </el-form-item>-->

      <el-form-item label="查询时间:">
        <el-date-picker
          v-model="timeRange"
          type="datetimerange"
          :picker-options="pickerOptions"
          range-separator="至"
          format="yyyy-MM-dd HH:mm:ss"
          value-format="timestamp"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          :clearable="false"
          :editable="false"
          @change="timeRangeOnChange"
        />
      </el-form-item>

      <el-form-item label="查询间隔:">
        <el-select
          v-model="timeSelectCondition"
          style="min-width: 260px"
          clearable
          filterable
          placeholder="请选择"
          @change="reloadRefreshTimer"
        >
          <el-option
            v-for="item in timeSelecteds"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </el-form-item>

      <el-form-item label="自动刷新:">
        <el-switch
          v-model="autoRefresh"
          active-color="#13ce66"
          inactive-color="#ff4949"
        />
      </el-form-item>

    </el-form>

    <el-card shadow="always">
      <div class="status-card-container">
        <div v-for="(item, index) in osStatus" :key="index" class="status-card">
          <div class="top-card-title">{{ item.label }}</div>
          <div class="top-card-detail">{{ item.value }}</div>
        </div>
      </div>
    </el-card>

    <el-card shadow="always" style="margin-top: 20px">
      <div class="card-header-title" style="display: flex; flex-direction: row; justify-content: space-between; align-items: center">
        <div style="display: flex; flex-direction: row; align-items: flex-end">
          告警诊断
          <el-popover
            v-model="triggerDialogVisible"
            placement="right"
            width="400"
            trigger="manual"
          >
            <el-form ref="triggerForm" :model="triggerForm" label-width="100px" style="margin-top: 20px">
              <el-form-item
                label="告警项："
                prop="target"
                :rules="[{ required: true, message: '告警项不能为空'}]"
              >
                <el-select v-model="triggerForm.target" placeholder="请选择告警项">
                  <el-option
                    v-for="item in triggerOptions"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  />
                </el-select>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" size="small" @click="triggerDialogVisible=false">取消</el-button>
                <el-button type="primary" size="small" @click="onTriggerCommit">确定</el-button>
              </el-form-item>
            </el-form>
            <div slot="reference" style="margin-left: 10px; color: #409EFF; font-size: 14px; cursor:pointer;" @click="triggerDialogVisible=true">
              （手动触发告警）
            </div>
          </el-popover>
        </div>
        <div v-if="alarmHistoaryRecentlyAllData.length > 2" style="font-size: 10px; color: #1890FF;" @click="alarmHistoaryDialogTableVisible=true">查看更多></div>
      </div>
      <el-divider />
      <div class="report-list-container">
        <el-table
          :data="alarmHistoaryRecentlyData"
          style="width: 100%"
          :height="(alarmHistoaryRecentlyData.length > 3 ? 3 : (alarmHistoaryRecentlyData.length === 0 ? 0 : alarmHistoaryRecentlyData.length-1)) * 60 + 110"
        >
          <el-table-column
            prop="level"
            label="等级"
            sortable
            width="80"
          >
            <template slot-scope="scope">
              <div v-if="scope.row.risk_level === '高级'" style="width: 40px; line-height: 20px; background: red; text-align: center; font-size: 10px">
                {{ scope.row.risk_level }}
              </div>
              <div v-if="scope.row.risk_level === '中级'" style="width: 40px; line-height: 20px; background: yellow; text-align: center; font-size: 10px">{{ scope
                .row.risk_level }}
              </div>
              <div
                v-if="scope.row.risk_level === '低级'"
                style="width: 40px; line-height: 20px; background: greenyellow; text-align: center;
                                font-size: 10px"
              >{{ scope.row.risk_level }}
              </div>
            </template>

          </el-table-column>
          <el-table-column
            prop="last_begin_time"
            label="发生时间"
            :formatter="startTimeFormatter"
            sortable
            width="160"
          />
          <el-table-column
            prop="anomaly_type"
            label="异常类型"
          />
          <el-table-column
            prop="description"
            label="异常描述"
            :show-overflow-tooltip="true"
          />
          <el-table-column
            prop="advice"
            label="建议"
            :show-overflow-tooltip="true"
          />
          <el-table-column
            label="回放"
            width="60"
          >
            <template slot-scope="scope">
              <el-popover
                width="800px"
                placement="left"
                trigger="click"
                @show="playback(scope)"
              >
                <div style="height: 800px;">
                  <lineChart class="detectorDiagnosticChart" :chart-option="detectorDiagnosticChartOption" />
                  <el-divider />
                  <div>
                    <span style="color: #333333; font-weight: bold">该时间段内的CPU进程：</span>
                    <el-table
                      :data="osProgressStateTableData"
                      :span-method="objectSpanMethod"
                      border
                      :height="430"
                      style="width: 100%; margin-top: 5px;"
                    >
                      <el-table-column
                        prop="start_at"
                        label="Time"
                        width="160"
                      />
                      <el-table-column
                        prop="uid"
                        label="uid"
                        width="80"
                      />
                      <el-table-column
                        prop="pid"
                        label="pid"
                        width="80"
                      />
                      <div v-if="osProgressStateType === 'io_saturation'">
                        <el-table-column
                          prop="kB_rd_s"
                          label="kB_rd/s"
                          width="80"
                        />
                        <el-table-column
                          prop="kB_wr_s"
                          label="kB_rd/s"
                          width="80"
                        />
                        <el-table-column
                          prop="kB_ccwr_s"
                          label="kB_ccwr/s"
                          width="80"
                        />
                        <el-table-column
                          prop="iodelay"
                          label="iodelay"
                          width="80"
                        />
                      </div>
                      <div v-else>
                        <el-table-column
                          prop="cpu_rate"
                          label="CPU(%)"
                          width="80"
                        />
                        <el-table-column
                          prop="mem_rate"
                          label="MEM(%)"
                          width="80"
                        />
                      </div>
                      <el-table-column
                        prop="commond"
                        label="Commond"
                      />
                    </el-table>
                  </div>
                </div>
                <div slot="reference" style="width: 30px; height: 30px;">
                  <svg
                    t="1616940117701"
                    class="icon"
                    viewBox="0 0 1024 1024"
                    version="1.1"
                    xmlns="http://www.w3.org/2000/svg"
                    p-id="1164"
                    width="30"
                    height="30"
                  >
                    <path
                      d="M277.398 874.572c0 11.78-9.53 21.34-21.34 21.34H128.088c-11.746 0-21.306-9.56-21.306-21.34V618.63c0-11.778 9.56-21.308 21.306-21.308h127.97c11.81 0 21.34 9.532 21.34 21.308v255.942z"
                      fill="#A0D468"
                      p-id="1165"
                    />
                    <path
                      d="M490.694 874.572c0 11.78-9.56 21.34-21.34 21.34h-127.97c-11.778 0-21.338-9.56-21.338-21.34V277.396c0-11.78 9.56-21.338 21.338-21.338h127.97c11.78 0 21.34 9.558 21.34 21.338v597.176z"
                      fill="#4FC2E9"
                      p-id="1166"
                    />
                    <path
                      d="M703.958 874.572c0 11.78-9.53 21.34-21.308 21.34H554.68c-11.78 0-21.34-9.56-21.34-21.34V490.66c0-11.78 9.56-21.306 21.34-21.306h127.968c11.78 0 21.308 9.528 21.308 21.306v383.912z"
                      fill="#48CFAD"
                      p-id="1167"
                    />
                    <path
                      d="M917.252 874.572c0 11.78-9.56 21.34-21.338 21.34h-127.972c-11.778 0-21.306-9.56-21.306-21.34V149.426c0-11.78 9.53-21.338 21.306-21.338h127.972c11.778 0 21.338 9.558 21.338 21.338v725.146z"
                      fill="#5D9CEC"
                      p-id="1168"
                    />
                    <path
                      d="M1002.576 853.266H21.458c-11.78 0-21.34 9.528-21.34 21.306s9.56 21.34 21.34 21.34h981.12c11.78 0 21.306-9.56 21.306-21.34s-9.528-21.306-21.308-21.306z"
                      fill="#434A54"
                      p-id="1169"
                    />
                  </svg>
                </div>
              </el-popover>

            </template>
          </el-table-column>

        </el-table>
      </div>
    </el-card>

    <div class="nineGridContainer">
      <el-card class="nineGrid" shadow="always">
        <div class="card-header-title">Average CPU Usage</div>
        <el-divider />
        <lineChart class="pgsqlLineChart" :chart-option="averageCPUUsageChartOption" />
      </el-card>

      <el-card class="nineGrid" shadow="always">
        <div class="card-header-title">Average Memory Usage</div>
        <el-divider />
        <lineChart class="pgsqlLineChart" :chart-option="averageMemoryUsageChartOption" />
      </el-card>

      <el-card class="nineGrid" shadow="always">
        <div class="card-header-title">Open File Descriptors</div>
        <el-divider />
        <lineChart class="pgsqlLineChart" :chart-option="openFileDescriptorsChartOption" />
      </el-card>

      <el-card class="nineGrid" shadow="always">
        <div class="card-header-title">Active sessions</div>
        <el-divider />
        <lineChart class="pgsqlLineChart" :chart-option="activeSessionsChartOption" />
      </el-card>

      <el-card class="nineGrid" style="width: calc(200% + 10px)" shadow="always">
        <div class="card-header-title">Buffers (bgwriter)</div>
        <el-divider />
        <lineChart class="pgsqlLineChart" :chart-option="buggersChartOption" />
      </el-card>
      <!--   占位   -->
      <div />

      <el-card class="nineGrid" style="width: calc(200% + 10px)" shadow="always">
        <div class="card-header-title">Checkpoint Stats</div>
        <el-divider />
        <lineChart class="pgsqlLineChart" :chart-option="checkpointStatsChartOption" />
      </el-card>
      <!--   占位   -->
      <div />

    </div>

    <el-dialog title="告警诊断" :visible.sync="alarmHistoaryDialogTableVisible" width="80%">
      <el-table
        :data="alarmHistoaryRecentlyAllData"
        style="width: 100%"
      >
        <el-table-column
          prop="level"
          label="等级"
          sortable
          width="80"
        >
          <template slot-scope="scope">
            <div v-if="scope.row.risk_level === '高级'" style="width: 40px; line-height: 20px; background: red; text-align: center; font-size: 10px">
              {{ scope.row.risk_level }}
            </div>
            <div v-if="scope.row.risk_level === '中级'" style="width: 40px; line-height: 20px; background: yellow; text-align: center; font-size: 10px">{{ scope
              .row.risk_level }}
            </div>
            <div
              v-if="scope.row.risk_level === '低级'"
              style="width: 40px; line-height: 20px; background: greenyellow; text-align: center;
                                font-size: 10px"
            >{{ scope.row.risk_level }}
            </div>
          </template>

        </el-table-column>
        <el-table-column
          prop="last_begin_time"
          label="发生时间"
          :formatter="startTimeFormatter"
          sortable
          width="160"
        />
        <el-table-column
          prop="anomaly_type"
          label="异常类型"
        />
        <el-table-column
          prop="description"
          label="异常描述"
          :show-overflow-tooltip="true"
        />
        <el-table-column
          prop="advice"
          label="建议"
        />
        <el-table-column
          label="回放"
          width="60"
        >
          <template slot-scope="scope">
            <el-popover
              width="800px"
              placement="left"
              trigger="click"
              @show="playback(scope)"
            >
              <div style="height: 800px;">
                <lineChart class="detectorDiagnosticChart" :chart-option="detectorDiagnosticChartOption" />
                <el-divider />
                <div>
                  <span style="color: #333333; font-weight: bold">该时间段内的CPU进程：</span>
                  <el-table
                    v-if="osProgressStateType === 'io_saturation'"
                    :data="osProgressStateTableData"
                    :span-method="objectSpanMethod"
                    border
                    :height="430"
                    style="width: 100%; margin-top: 5px;"
                  >
                    <el-table-column
                      prop="start_at"
                      label="Time"
                      width="160"
                    />
                    <el-table-column
                      prop="uid"
                      label="uid"
                      width="80"
                    />
                    <el-table-column
                      prop="pid"
                      label="pid"
                      width="80"
                    />
                    <el-table-column
                      prop="kB_rd_s"
                      label="kB_rd/s"
                      width="80"
                    />
                    <el-table-column
                      prop="kB_wr_s"
                      label="kB_rd/s"
                      width="80"
                    />
                    <el-table-column
                      prop="kB_ccwr_s"
                      label="kB_ccwr/s"
                      width="80"
                    />
                    <el-table-column
                      prop="iodelay"
                      label="iodelay"
                      width="80"
                    />
                    <el-table-column
                      prop="commond"
                      label="Commond"
                    />
                  </el-table>
                  <el-table
                    v-else
                    :data="osProgressStateTableData"
                    :span-method="objectSpanMethod"
                    border
                    :height="430"
                    style="width: 100%; margin-top: 5px;"
                  >
                    <el-table-column
                      prop="start_at"
                      label="Time"
                      width="160"
                    />
                    <el-table-column
                      prop="uid"
                      label="uid"
                      width="80"
                    />
                    <el-table-column
                      prop="pid"
                      label="pid"
                      width="80"
                    />
                    <el-table-column
                      prop="cpu_rate"
                      label="CPU(%)"
                      width="80"
                    />
                    <el-table-column
                      prop="commond"
                      label="Commond"
                    />
                  </el-table>
                </div>
              </div>
              <div slot="reference" style="width: 30px; height: 30px;">
                <svg t="1616940117701" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1164" width="30" height="30">
                  <path
                    d="M277.398 874.572c0 11.78-9.53 21.34-21.34 21.34H128.088c-11.746 0-21.306-9.56-21.306-21.34V618.63c0-11.778 9.56-21.308 21.306-21.308h127.97c11.81 0 21.34 9.532 21.34 21.308v255.942z"
                    fill="#A0D468"
                    p-id="1165"
                  />
                  <path
                    d="M490.694 874.572c0 11.78-9.56 21.34-21.34 21.34h-127.97c-11.778 0-21.338-9.56-21.338-21.34V277.396c0-11.78 9.56-21.338 21.338-21.338h127.97c11.78 0 21.34 9.558 21.34 21.338v597.176z"
                    fill="#4FC2E9"
                    p-id="1166"
                  />
                  <path
                    d="M703.958 874.572c0 11.78-9.53 21.34-21.308 21.34H554.68c-11.78 0-21.34-9.56-21.34-21.34V490.66c0-11.78 9.56-21.306 21.34-21.306h127.968c11.78 0 21.308 9.528 21.308 21.306v383.912z"
                    fill="#48CFAD"
                    p-id="1167"
                  />
                  <path
                    d="M917.252 874.572c0 11.78-9.56 21.34-21.338 21.34h-127.972c-11.778 0-21.306-9.56-21.306-21.34V149.426c0-11.78 9.53-21.338 21.306-21.338h127.972c11.778 0 21.338 9.558 21.338 21.338v725.146z"
                    fill="#5D9CEC"
                    p-id="1168"
                  />
                  <path
                    d="M1002.576 853.266H21.458c-11.78 0-21.34 9.528-21.34 21.306s9.56 21.34 21.34 21.34h981.12c11.78 0 21.306-9.56 21.306-21.34s-9.528-21.306-21.308-21.306z"
                    fill="#434A54"
                    p-id="1169"
                  />
                </svg>
              </div>
            </el-popover>

          </template>
        </el-table-column>

      </el-table>
      <el-pagination
        class="pagination"
        style="margin-top: 5px"
        background=""
        layout="prev, pager, next"
        :current-page="pageIndex"
        :page-size="pageSize"
        :total="totalItems"
        @current-change="curPageChange"
      />
    </el-dialog>

  </div>
</template>

<script>

import { query, query_range } from '../../../api/prometheus'
import { formatSeconds, bytesToSize, stringFoFixed2 } from '../../../utils/index'
import lineChart from '../../../components/echarts/vue-chart'
import { lineChartOption } from '../../../utils/echart-ori-options'
import { pickerOptions } from '../../../utils/date_time_picker_options'
import moment from 'moment'
import { pgsqlDetectorAndDiagnostic, mysqlAnomalyTrigger, osProgressStateHistory } from '../../../api/api'

export default {
  components: { lineChart },
  filters: {
    percentageFilter: function(value) {
      if (!value) {
        return ''
      }
      return Math.round(value * 100) / 100.0 + '%'
    }
  },
  data() {
    return {
      triggerDialogVisible: false,
      triggerForm: {
        target: ''
      },
      triggerOptions: [
        { label: 'cpu_saturation', value: '0' },
        { label: 'io_saturation', value: '1' },
        { label: 'database_backup', value: '2' },
        { label: 'table_restore', value: '3' },
        { label: 'poorly_physical_design', value: '4' },
        { label: 'poorly_written_query', value: '5' },
        { label: 'workload_spike', value: '6' },
        { label: 'network_congestion', value: '7' },
        { label: 'lock_contention', value: '8' },
        { label: 'vacuum_analyze', value: '9' }
      ],
      osProgressStateTableData: [],
      osProgressStateType: '',
      instanceSelecteds: [],
      instanceSelectCondition: undefined,
      databaseSelecteds: [],
      databaseSelectCondition: undefined,
      autoRefresh: false,
      timeSelecteds: [
        { label: '5s', value: '5s' },
        { label: '10s', value: '10s' },
        { label: '30s', value: '30s' },
        { label: '1m', value: '1m' },
        { label: '2m', value: '2m' },
        { label: '3m', value: '3m' },
        { label: '5m', value: '5m' },
        { label: '10m', value: '10m' },
        { label: '30m', value: '30m' }
      ],
      timeSelectedToMs: {
        '5s': 5000,
        '10s': 10000,
        '30s': 30000,
        '1m': 60000,
        '2m': 120000,
        '3m': 180000,
        '5m': 300000,
        '10m': 6000000,
        '30m': 18000000
      },
      timeSelectCondition: '2m',
      refreshTimer: undefined,
      pickerOptions: pickerOptions,
      timeRange: [],
      osStatus: [
        { label: '运行时间', value: '' },
        { label: 'Current Fetch Data', value: '' },
        { label: 'Current Insert Data', value: '' },
        { label: 'Current Update Data', value: '' },
        { label: 'Shared Buffers', value: '' },
        { label: 'Effective Cache', value: '' },
        { label: 'Maintenance Work Mem', value: '' },
        { label: 'Work Mem', value: '' },
        { label: 'Max Wal Size', value: '' },
        { label: 'Random Page Cost', value: '' },
        { label: 'Seq Page Cost', value: '' },
        { label: 'Max Worker Processes', value: '' },
        { label: 'Max Parallel Workers', value: '' }
      ],
      loading: false,
      pageSize: 8,
      pageIndex: 1,
      totalItems: 0,
      alarmHistoaryRecentlyData: [],
      alarmHistoaryRecentlyAllData: [],
      alarmHistoaryDialogTableVisible: false,
      averageCPUUsageChartOption: JSON.parse(JSON.stringify(lineChartOption)),
      averageMemoryUsageChartOption: JSON.parse(JSON.stringify(lineChartOption)),
      openFileDescriptorsChartOption: JSON.parse(JSON.stringify(lineChartOption)),
      activeSessionsChartOption: JSON.parse(JSON.stringify(lineChartOption)),
      buggersChartOption: JSON.parse(JSON.stringify(lineChartOption)),
      checkpointStatsChartOption: JSON.parse(JSON.stringify(lineChartOption)),
      detectorDiagnosticChartOption: JSON.parse(JSON.stringify(lineChartOption))
    }
  },
  watch: {
    instanceSelectCondition(value) {
      this.reloadRequest()
    },
    timeSelectCondition(value) {
      this.reloadRequest()
    }
  },
  mounted() {
    this.timeRange = [moment().add(-1, 'h').format('x'), moment().format('x')]

    //  Average CPU UsageChart
    this.averageCPUUsageChartOption.tooltip.formatter = function(params, ticket, callback) {
      var result = params[0].axisValueLabel + '</br>'
      for (let i = 0; i < params.length; i++) {
        const param = params[i]
        result = result + `${param.marker}&nbsp${param.seriesName}:&nbsp ${stringFoFixed2(param.value[1] * 1000)}ms</br>`
      }
      setTimeout(function() {
        // 仅为了模拟异步回调
        callback(ticket, result)
      }, 100)
      return 'loading...'
    }
    this.averageCPUUsageChartOption.yAxis.axisLabel.formatter = function(value, index) {
      return stringFoFixed2(value * 1000) + 'ms'
    }
    this.averageCPUUsageChartOption.xAxis.type = 'time'
    this.averageCPUUsageChartOption.color = ['#00FFFF']
    this.averageCPUUsageChartOption.xAxis.axisLabel.formatter = '{HH}:{mm}'
    this.averageCPUUsageChartOption.legend.data = ['CPU Time']
    this.averageCPUUsageChartOption.series = [
      {
        name: 'CPU Time',
        data: [],
        type: 'line',
        smooth: true,
        showSymbol: false,
        areaStyle: { type: 'default' }
      }
    ]

    //  Average Memory Usage
    this.averageMemoryUsageChartOption.tooltip.formatter = function(params, ticket, callback) {
      var result = params[0].axisValueLabel + '</br>'
      for (let i = 0; i < params.length; i++) {
        const param = params[i]
        result = result + `${param.marker}&nbsp${param.seriesName}:&nbsp ${bytesToSize(param.value[1])}</br>`
      }
      setTimeout(function() {
        // 仅为了模拟异步回调
        callback(ticket, result)
      }, 100)
      return 'loading...'
    }
    this.averageMemoryUsageChartOption.yAxis.axisLabel.formatter = function(value, index) {
      return bytesToSize(value)
    }
    this.averageMemoryUsageChartOption.xAxis.type = 'time'
    this.averageMemoryUsageChartOption.color = ['#975FE4', '#01DF3A']
    this.averageMemoryUsageChartOption.xAxis.axisLabel.formatter = '{HH}:{mm}'
    this.averageMemoryUsageChartOption.legend.data = ['Resident Mem', 'Virtual Mem']
    this.averageMemoryUsageChartOption.series = [
      {
        name: 'Resident Mem',
        data: [],
        type: 'line',
        smooth: true,
        showSymbol: false,
        areaStyle: { type: 'default' }
      },
      {
        name: 'Virtual Mem',
        data: [],
        type: 'line',
        smooth: true,
        showSymbol: false,
        areaStyle: { type: 'default' }
      }
    ]

    //  Open File Descriptors
    this.openFileDescriptorsChartOption.tooltip.formatter = function(params, ticket, callback) {
      var result = params[0].axisValueLabel + '</br>'
      for (let i = 0; i < params.length; i++) {
        const param = params[i]
        result = result + `${param.marker}&nbsp${param.seriesName}:&nbsp ${stringFoFixed2(param.value[1])}</br>`
      }
      setTimeout(function() {
        // 仅为了模拟异步回调
        callback(ticket, result)
      }, 100)
      return 'loading...'
    }
    this.openFileDescriptorsChartOption.xAxis.type = 'time'
    this.openFileDescriptorsChartOption.color = ['#1890FF']
    this.openFileDescriptorsChartOption.xAxis.axisLabel.formatter = '{HH}:{mm}'
    this.openFileDescriptorsChartOption.legend.data = ['Open FD']
    this.openFileDescriptorsChartOption.series = [
      {
        name: 'Open FD',
        data: [],
        type: 'line',
        smooth: true,
        showSymbol: false
      }
    ]

    // Active sessions
    this.activeSessionsChartOption.tooltip.formatter = function(params, ticket, callback) {
      var result = params[0].axisValueLabel + '</br>'
      for (let i = 0; i < params.length; i++) {
        const param = params[i]
        result = result + `${param.marker}&nbsp${param.seriesName}:&nbsp ${stringFoFixed2(param.value[1])}</br>`
      }
      setTimeout(function() {
        // 仅为了模拟异步回调
        callback(ticket, result)
      }, 100)
      return 'loading...'
    }
    this.activeSessionsChartOption.xAxis.type = 'time'
    this.activeSessionsChartOption.color = ['#01DF3A', '#FFFF00', '#1890FF']
    this.activeSessionsChartOption.xAxis.axisLabel.formatter = '{HH}:{mm}'
    this.activeSessionsChartOption.legend.data = ['dbmind']
    this.activeSessionsChartOption.series = [
      {
        name: 'dbmind',
        data: [],
        type: 'line',
        smooth: true,
        showSymbol: false,
        areaStyle: { type: 'default' }
      }
    ]

    // Buffers (bgwriter)
    this.buggersChartOption.tooltip.formatter = function(params, ticket, callback) {
      var result = params[0].axisValueLabel + '</br>'
      for (let i = 0; i < params.length; i++) {
        const param = params[i]
        result = result + `${param.marker}&nbsp${param.seriesName}:&nbsp ${stringFoFixed2(param.value[1])}</br>`
      }
      setTimeout(function() {
        // 仅为了模拟异步回调
        callback(ticket, result)
      }, 100)
      return 'loading...'
    }
    this.buggersChartOption.xAxis.type = 'time'
    this.buggersChartOption.color = ['#FE2E2E', '#00FFFF', '#1890FF']
    this.buggersChartOption.xAxis.axisLabel.formatter = '{HH}:{mm}'
    this.buggersChartOption.legend.data = ['buffers_backend', 'buffers_alloc', 'backend_fsync', 'buffers_checkpoint', 'buffers_clean']
    this.buggersChartOption.series = [
      {
        name: 'buffers_backend',
        data: [],
        type: 'line',
        smooth: true,
        showSymbol: false,
        areaStyle: { type: 'default' }
      },
      {
        name: 'buffers_alloc',
        data: [],
        type: 'line',
        smooth: true,
        showSymbol: false,
        areaStyle: { type: 'default' }
      },
      {
        name: 'backend_fsync',
        data: [],
        type: 'line',
        smooth: true,
        showSymbol: false,
        areaStyle: { type: 'default' }
      },
      {
        name: 'buffers_checkpoint',
        data: [],
        type: 'line',
        smooth: true,
        showSymbol: false,
        areaStyle: { type: 'default' }
      },
      {
        name: 'buffers_clean',
        data: [],
        type: 'line',
        smooth: true,
        showSymbol: false,
        areaStyle: { type: 'default' }
      }
    ]

    //  Checkpoint Stats
    this.checkpointStatsChartOption.tooltip.formatter = function(params, ticket, callback) {
      var result = params[0].axisValueLabel + '</br>'
      for (let i = 0; i < params.length; i++) {
        const param = params[i]
        result = result + `${param.marker}&nbsp${param.seriesName}:&nbsp ${stringFoFixed2(param.value[1] * 1000)}ms</br>`
      }
      setTimeout(function() {
        // 仅为了模拟异步回调
        callback(ticket, result)
      }, 100)
      return 'loading...'
    }
    this.checkpointStatsChartOption.yAxis.axisLabel.formatter = function(value, index) {
      return stringFoFixed2(value * 1000) + 'ms'
    }
    this.checkpointStatsChartOption.xAxis.type = 'time'
    this.checkpointStatsChartOption.color = ['#00FFFF']
    this.checkpointStatsChartOption.xAxis.axisLabel.formatter = '{HH}:{mm}'
    this.checkpointStatsChartOption.legend.data = ['write_time', 'sync_time']
    this.checkpointStatsChartOption.series = [
      {
        name: 'write_time',
        data: [],
        type: 'line',
        smooth: true,
        showSymbol: false,
        areaStyle: { type: 'default' }
      },
      {
        name: 'sync_time',
        data: [],
        type: 'line',
        smooth: true,
        showSymbol: false,
        areaStyle: { type: 'default' }
      }
    ]

    // detectorDiagnostic
    this.detectorDiagnosticChartOption.tooltip.formatter = function(params, ticket, callback) {
      var result = params[0].axisValueLabel + '</br>'
      for (let i = 0; i < params.length; i++) {
        const param = params[i]
        result = result + `${param.marker}&nbsp${param.seriesName}(${param.value[2]}):&nbsp ${param.value[1]}</br>`
      }
      setTimeout(function() {
        // 仅为了模拟异步回调
        callback(ticket, result)
      }, 100)
      return 'loading...'
    }
    this.detectorDiagnosticChartOption.xAxis.type = 'time'
    this.detectorDiagnosticChartOption.grid.left = 60
    this.detectorDiagnosticChartOption.grid.top = 30
    this.detectorDiagnosticChartOption.grid.bottom = 50
    this.detectorDiagnosticChartOption.xAxis.axisLabel.formatter = '{HH}:{mm}'

    this.nodesInfo()
  },
  beforeDestroy() {
    this.clearRefreshTimer()
  },
  methods: {
    onTriggerCommit() {
      this.triggerDialogVisible = false
      mysqlAnomalyTrigger({ target: this.triggerForm.target }).then(res => {
        this.$message.success('任务已经添加，请等待')
      })
    },
    startTimeFormatter(row, column) {
      return moment(row.last_begin_time).format('YYYY-MM-DD HH:mm:ss')
    },
    playback(scope) {
      const list = JSON.parse(scope.row.anomaly_metrics_list)
      this.detectorDiagnosticChartOption.series = []
      this.detectorDiagnosticChartOption.legend.data = []
      for (let i = 0; i < list.length; i++) {
        this.detectorDiagnosticChartOption.legend.data.push(list[i].name)
        const data = list[i].data
        for (let j = 0; j < data.length; j++) {
          const item = data[j]
          item[0] = moment(item[0]).format('YYYY-MM-DD HH:mm:ss')
          item[1] = stringFoFixed2(item[1])
          item[2] = list[i].name_value
        }
        this.detectorDiagnosticChartOption.series.push(
          {
            name: list[i].name,
            data: data,
            type: 'line',
            smooth: true,
            showSymbol: false,
            areaStyle: { type: 'default' }
          }
        )
      }
      this.osProgressStateType = scope.row.anomaly_type
      console.log(scope.row)
      this.getOsProgressStateHistory(scope.row.last_begin_time)
    },
    getOsProgressStateHistory(start_at) {
      osProgressStateHistory({
        instance: '8.131.229.55:9104',
        start_at: moment(start_at).add(-1, 'minutes').format('YYYY-MM-DD HH:mm:ss'),
        end_at: moment(start_at).add(1, 'minutes').format('YYYY-MM-DD HH:mm:ss'),
        sort_type: this.osProgressStateType === 'io_saturation' ? this.osProgressStateType : 'cpu_saturation'
      }).then(res => {
        this.osProgressStateTableData = []
        const data = res.data
        for (let i = 0; i < data.length; i++) {
          const item = data[i]
          const list = JSON.parse(item['history_json'])
          for (let j = 0; j < Math.min(list.length, 5); j++) {
            var progress = list[j]
            progress['start_at'] = item['start_at']
            console.log(progress['start_at'])
            this.osProgressStateTableData.push(progress)
          }
        }
      })
    },
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 0) {
        if (rowIndex % 5 === 0) {
          return {
            rowspan: 5,
            colspan: 1
          }
        } else {
          return {
            rowspan: 0,
            colspan: 0
          }
        }
      }
    },
    pgsqlDetectorAndDiagnostic() {
      pgsqlDetectorAndDiagnostic({ instance: '8.131.229.55:9104', page: this.pageIndex, page_size: this.pageSize }).then((res) => {
        if (res.data) {
          this.totalItems = res.count
          this.alarmHistoaryRecentlyAllData = JSON.parse(JSON.stringify(res.data))
          this.alarmHistoaryRecentlyData = res.data.splice(0, 2)
        }
      }).catch(() => {
        this.loading = false
      })
    },
    timeRangeOnChange() {
      if (this.timeRange && this.timeRange.length > 1) {
        this.reloadRequest()
      }
    },
    reloadRefreshTimer() {
      this.clearRefreshTimer()
      this.refreshTimer = setInterval(() => {
        console.log('执行')
        if (this.autoRefresh) {
          this.timeRange = [moment().add(-1, 'h').format('x'), moment().format('x')]
          this.reloadRequest()
        }
      }, this.timeSelectedToMs[this.timeSelectCondition])
    },
    clearRefreshTimer() {
      console.log('清除')
      clearInterval(this.refreshTimer)
      this.refreshTimer = null
    },
    nodesInfo() {
      query({ 'query': 'pg_exporter_last_scrape_duration_seconds', time: parseInt((new Date()).valueOf() / 1000) - 1000 }).then(res => {
        const data = res.data.data
        if (data && data.result && data.result.length > 0) {
          const result = data.result
          var selecteds = []
          for (let i = 0; i < result.length; i++) {
            selecteds.push(result[i].metric)
          }
          this.instanceSelecteds = selecteds
          this.instanceSelectCondition = this.instanceSelecteds[0].instance
        }
      })
    },
    reloadRequest() {
      if (!this.instanceSelectCondition) {
        return
      }
      this.pgsqlDetectorAndDiagnostic()
      this.queryRequest(`pg_postmaster_start_time_seconds{release="", instance=~"${this.instanceSelectCondition}"} * 1000`).then(res => {
        this.osStatus[0].value = res ? formatSeconds(res) : 'No Data'
      })

      this.queryRequest(`SUM(pg_stat_database_tup_fetched{datname=~"(dbmind|postgres|template0|template1)", instance=~"${this.instanceSelectCondition}"})`).then(res => {
        this.osStatus[1].value = res ? bytesToSize(res) : 'No Data'
      })

      this.queryRequest(`SUM(pg_stat_database_tup_inserted{release="", datname=~"(dbmind|postgres|template0|template1)", instance=~"${this.instanceSelectCondition}"})`).then(res => {
        this.osStatus[2].value = res ? bytesToSize(res) : 'No Data'
      })

      this.queryRequest(`SUM(pg_stat_database_tup_updated{release="", datname=~"(dbmind|postgres|template0|template1)", instance=~"${this.instanceSelectCondition}"})`).then(res => {
        this.osStatus[3].value = res ? bytesToSize(res) : 'No Data'
      })

      this.queryRequest(`pg_settings_shared_buffers_bytes{instance=~"${this.instanceSelectCondition}"}`).then(res => {
        this.osStatus[4].value = res ? bytesToSize(res) : 'No Data'
      })

      this.queryRequest(`pg_settings_effective_cache_size_bytes{instance=~"${this.instanceSelectCondition}"}`).then(res => {
        this.osStatus[5].value = res ? bytesToSize(res) : 'No Data'
      })

      this.queryRequest(`pg_settings_maintenance_work_mem_bytes{instance=~"${this.instanceSelectCondition}"}`).then(res => {
        this.osStatus[6].value = res ? bytesToSize(res) : 'No Data'
      })

      this.queryRequest(`pg_settings_work_mem_bytes{instance=~"${this.instanceSelectCondition}"}`).then(res => {
        this.osStatus[7].value = res ? bytesToSize(res) : 'No Data'
      })

      this.queryRequest(`pg_settings_max_wal_size_bytes{instance=~"${this.instanceSelectCondition}"}`).then(res => {
        this.osStatus[8].value = res ? bytesToSize(res) : 'No Data'
      })

      this.queryRequest(`pg_settings_random_page_cost{instance=~"${this.instanceSelectCondition}"}`).then(res => {
        this.osStatus[9].value = res || 'No Data'
      })

      this.queryRequest(`pg_settings_seq_page_cost{instance=~"${this.instanceSelectCondition}"}`).then(res => {
        this.osStatus[10].value = res || 'No Data'
      })

      this.queryRequest(`pg_settings_max_worker_processes{instance=~"${this.instanceSelectCondition}"}`).then(res => {
        this.osStatus[11].value = res || 'No Data'
      })

      this.queryRequest(`pg_settings_max_parallel_workers{instance=~"${this.instanceSelectCondition}"}`).then(res => {
        this.osStatus[12].value = res || 'No Data'
      })

      this.queryRangeRequest(`avg(rate(process_cpu_seconds_total{release="", instance="${this.instanceSelectCondition}"}[${this.timeSelectCondition}]) * 1000)`).then(res => {
        this.averageCPUUsageChartOption.series[0].data = res
      })

      this.queryRangeRequest(`avg(rate(process_resident_memory_bytes{release="", instance="${this.instanceSelectCondition}"}[${this.timeSelectCondition}]))`).then(res => {
        this.averageMemoryUsageChartOption.series[0].data = res
      })

      this.queryRangeRequest(`avg(rate(process_virtual_memory_bytes{release="", instance="${this.instanceSelectCondition}"}[${this.timeSelectCondition}]))`).then(res => {
        this.averageMemoryUsageChartOption.series[1].data = res
      })

      this.queryRangeRequest(`process_open_fds{release="", instance="${this.instanceSelectCondition}"}`).then(res => {
        this.openFileDescriptorsChartOption.series[0].data = res
      })

      this.queryRangeRequest(`pg_stat_activity_count{datname=~"(dbmind|postgres|template0|template1)", instance=~"${this.instanceSelectCondition}", state="active"} !=0`).then(res => {
        this.activeSessionsChartOption.series[0].data = res
      })

      this.queryRangeRequest(`irate(pg_stat_bgwriter_buffers_backend{instance="${this.instanceSelectCondition}"}[${this.timeSelectCondition}])`).then(res => {
        this.buggersChartOption.series[0].data = res
      })

      this.queryRangeRequest(`irate(pg_stat_bgwriter_buffers_alloc{instance="${this.instanceSelectCondition}"}[${this.timeSelectCondition}])`).then(res => {
        this.buggersChartOption.series[1].data = res
      })

      this.queryRangeRequest(`irate(pg_stat_bgwriter_buffers_backend_fsync{instance="${this.instanceSelectCondition}"}[${this.timeSelectCondition}])`).then(res => {
        this.buggersChartOption.series[2].data = res
      })

      this.queryRangeRequest(`irate(pg_stat_bgwriter_buffers_checkpoint{instance="${this.instanceSelectCondition}"}[${this.timeSelectCondition}])`).then(res => {
        this.buggersChartOption.series[3].data = res
      })

      this.queryRangeRequest(`irate(pg_stat_bgwriter_buffers_clean{instance="${this.instanceSelectCondition}"}[${this.timeSelectCondition}])`).then(res => {
        this.buggersChartOption.series[4].data = res
      })

      this.queryRangeRequest(`irate(pg_stat_bgwriter_checkpoint_write_time{instance="${this.instanceSelectCondition}"}[${this.timeSelectCondition}])`).then(res => {
        this.checkpointStatsChartOption.series[0].data = res
      })

      this.queryRangeRequest(`irate(pg_stat_bgwriter_checkpoint_sync_time{instance="${this.instanceSelectCondition}"}[${this.timeSelectCondition}])`).then(res => {
        this.checkpointStatsChartOption.series[1].data = res
      })
    },
    queryRequest(queryUrl) {
      return new Promise((resolve, reject) => {
        query({ query: queryUrl }).then(res => {
          const data = res.data.data
          if (data && data.result && data.result.length > 0 && data.result[0].value) {
            resolve(data.result[0].value[1])
          } else {
            resolve(undefined)
          }
        })
      })
    },
    queryRangeRequest(queryUrl, original = false) {
      return new Promise((resolve, reject) => {
        query_range({
          query: queryUrl,
          start: this.timeRange[0] ? this.timeRange[0] / 1000 : (new Date()).valueOf() / 1000 - 3600 * 24,
          end: this.timeRange[1] ? this.timeRange[1] / 1000 : (new Date()).valueOf() / 1000,
          step: parseInt(this.timeSelectedToMs[this.timeSelectCondition]) / 1000
        }).then(res => {
          const data = res.data.data
          if (data && data.result && data.result.length > 0) {
            if (original) {
              resolve(res)
            } else {
              if (data.result[0].values.length > 0) {
                const values = data.result[0].values
                var results = []
                for (let i = 0; i < values.length; i++) {
                  const value = values[i]
                  results.push([value[0] * 1000, value[1]])
                }
                resolve(results)
              } else {
                resolve(undefined)
              }
            }
          } else {
            resolve(undefined)
          }
        })
      })
    },
    async curPageChange(page) {
      this.pageIndex = page
      this.pgsqlDetectorAndDiagnostic()
    }
  }
}
</script>

<style lang="scss" scoped>

  .container {
    display: flex;
    flex-direction: column;
    width: 100%;
  }

  .status-card-container {
    margin: auto;
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    overflow-x: auto;
  }

  .status-card {
    min-width: 80px;
    margin-right: 10px;
    display: flex;
    min-height: 50px;
    flex-direction: column;
    justify-content: flex-start;
  }

  .top-card-title {
    color: rgba(0, 0, 0, 0.45);
    font-size: 12px;
    text-align: center;
    height: 20px;
  }

  .top-card-detail {
    color: rgba(0, 0, 0, 0.85);
    font-weight: bolder;
    font-size: 18px;
    margin-top: 5px;
    text-align: center;
  }

  .card-header-title {
    color: rgba(0, 0, 0, 0.85);
    font-weight: 500;
    white-space: nowrap;
    word-break: break-all;
    font-size: 18px;
  }

  .el-divider--horizontal {
    margin: 20px 0;
  }

  .el-col-5 {
    width: 20%;
  }

  .nineGridContainer {
    display: grid;
    grid-template-columns: repeat(2, 1fr); /* 相当于 1fr 1fr 1fr */
    grid-template-rows: repeat(2, 1fr); /* fr单位可以将容器分为几等份 */
    grid-gap: 10px; /* grid-column-gap 和 grid-row-gap的简写 */
    grid-auto-flow: row;
    .nineGrid{
      background-color: #FFFFFF;
    }
    margin-top: 20px;
  }

  .pgsqlLineChart {
    width: 100%;
    height: 200px;
  }

  .detectorDiagnosticChart {
    width: 800px;
    height: 300px;
  }

</style>
